package com.itita.ww2.handler.requesthandler.account;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Arrays;

import javax.security.auth.login.LoginException;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

import com.smartfoxserver.v2.components.login.LoginAssistantComponent;
import com.smartfoxserver.v2.components.login.PasswordCheckException;
import com.smartfoxserver.v2.db.SFSDBManager;
import com.smartfoxserver.v2.extensions.SFSExtension;
import com.smartfoxserver.v2.security.DefaultPermissionProfile;
import com.smartfoxserver.v2.util.MD5;
import com.itita.ww2.enums.ChannelEnum;
import com.itita.ww2.model.LoginInfo;
import com.itita.ww2.utils.TimeUtil;
import com.itita.ww2.utils.properties.ServerProperties;

/**
 * @author Lan manage account SignUp , Login ,
 *         PasswordRecover($SignUp.PasswordRecover)
 */
public class LoginComponent {
	private LoginAssistantComponent lac;

	public SFSExtension ext;

	public LoginComponent(SFSExtension ext) {
		this.ext = ext;

		initLoginAssistant();
	}

	public void destroy() {
		lac.destroy();
	}

	private void initLoginAssistant() {
		lac = new LoginAssistantComponent(ext);

		lac.getConfig().loginTable = "users";
		lac.getConfig().userNameField = "username";
		lac.getConfig().passwordField = "password";
		lac.getConfig().nickNameField = "nickname";
		lac.getConfig().extraFields = Arrays.asList("id", "country", "pwd_salt", "channel", "channelId");
		lac.getConfig().customPasswordCheck = true;

		lac.getConfig().preProcessPlugin = loginData -> {
			int channel = loginData.extraFields.getInt("channel");

			// 分渠道登录模块
			if (channel == ChannelEnum.OFFICIAL.getValue()) {
				// 官方渠道(用户名密码登录)
				if (!loginData.password.equals(loginData.clientIncomingData.getUtfString("password"))) {
					throw new PasswordCheckException();
				}
			} else {
				// 其它渠道
				// 再次组合密码 -> 与传入密码比对 -> 组合实际密码 -> 与password栏比对
				String pwdBack = MD5.getInstance()
						.getHash(loginData.userName + ServerProperties.getString("my.salt", "_nl"));
				if (!pwdBack.equals(loginData.clientIncomingData.getUtfString("password"))) {
					throw new PasswordCheckException();
				}
				// 组合实际密码比对
				String pwdReal = MD5.getInstance()
						.getHash(loginData.userName + ServerProperties.getString("my.salt", "_nl")
								+ loginData.extraFields.getUtfString("pwd_salt"));
				if (!pwdReal.equals(loginData.password)) {
					throw new PasswordCheckException();
				}
			}
		};

		lac.getConfig().postProcessPlugin = arg0 -> {
			// 设置权限
			arg0.session.setProperty("$permission", DefaultPermissionProfile.STANDARD);

			LoginInfo loginInfo = new LoginInfo(arg0);
			int uid = loginInfo.uid;
			arg0.session.setProperty("loginInfo", loginInfo);

			/**
			 * 回传数据给客户端
			 */
			arg0.clientOutGoingData.putLong("time", TimeUtil.getUtcNow().getMillis()); // 服务器时间
			arg0.clientOutGoingData.putInt("uid", uid); // uid
			/**
			 * 更新用户信息
			 */

			// 在线状态
			//			if (DBManager.getInstance().havePlayer(uid)) {
			//				DBManager.getInstance().updateUserState(uid, 2);
			//			}

			SFSDBManager dbManager = (SFSDBManager) ext.getParentZone().getDBManager();
			// 更新登录时间
			try {
				String sql = "UPDATE users SET lastTime = ? WHERE id = ?";
				dbManager.executeUpdate(sql,
						Arrays.asList(new Timestamp(DateTime.now(DateTimeZone.UTC).getMillis()), uid).toArray());
			} catch (SQLException e) {
				e.printStackTrace();
				throw new LoginException("[ERROR - 4] Server Error!");
			}

			ext.trace("[" + arg0.nickName + "] Login.");
		};
	}
}
